/*
 *  Copyrigh 2009 Codeinn
 *  This program is distributed under the terms of the GNU General Public License
 *
 *  This file is part of Codeinn.
 * 
 *  Codeinn is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Codeinn is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Codeinn.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package http;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.ConnectionNotFoundException;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;


public class DJangoConnection {
    
    // Return types
    private static final int STRING = 0;
    private static final int INPUT_STREAM = 1;

    public DJangoConnection() {}

    public String httpLogin(String url, String user, String password) throws IOException {
        String[] keys = {"user", "password"};
        String[] values = {user, password};
        String encodedData = this.encode(keys, values);
        String response = (String) this.httpConnection(url, encodedData, DJangoConnection.STRING);
        System.out.println("    DJangoConnection.httpLogin -> "+response);
        return response;
    }

    public InputStream httpFetchAvailableVideosList(String url, String user) throws IOException {
        String[] keys = {"user"};
        String[] values = {user};
        String encodedData = this.encode(keys, values);
        return (InputStream) this.httpConnection(url, encodedData, DJangoConnection.INPUT_STREAM);
    }

    public InputStream httpFetchGroups(String url, String user) throws IOException {
        String[] keys = {"user"};
        String[] values = {user};
        String encodedData = this.encode(keys, values);
        return (InputStream) this.httpConnection(url, encodedData, DJangoConnection.INPUT_STREAM);
    }

    public InputStream httpFetchThreads(String url, String course, String group) throws IOException {
        String[] keys = {"course", "group"};
        String[] values = {course, group};
        String encodedData = this.encode(keys, values);
        //System.out.println(" Threads: "+encodedData);
        return (InputStream) this.httpConnection(url, encodedData, DJangoConnection.INPUT_STREAM);
    }

    public InputStream httpFetchPosts(String url, String thread) throws IOException {
        String[] keys = {"thread"};
        String[] values = {thread};
        String encodedData = this.encode(keys, values);
        return (InputStream) this.httpConnection(url, encodedData, DJangoConnection.INPUT_STREAM);
    }

    public InputStream httpFetchVideo(String videoURL) throws IOException {
        return (InputStream) this.httpConnection(videoURL, null, DJangoConnection.INPUT_STREAM);
    }

    /**
     *
     * This is the brain, the code that actually does a httpconnection
     * encodedData: If its NOT null, a POST to the server will be done with the data, it must be encoded already.
     * 
     */
    private Object httpConnection(String url, String encodedData, int RETURN_TYPE) throws IOException {
        HttpConnection httpConnection = null;
        try {
          boolean timeoutExceptions = true;
          httpConnection = (HttpConnection)Connector.open(url, Connector.READ_WRITE, timeoutExceptions);
          // POST
          if(encodedData != null)
              this.postEncodedData(httpConnection, encodedData);
          int respondCode = httpConnection.getResponseCode();
          System.out.println("    "+RETURN_TYPE+" "+respondCode+" "+httpConnection.getResponseMessage());
          // Read response
          if(respondCode == 200) { //HTTP/1.0 200 OK
              InputStream inputStream = httpConnection.openInputStream();
              if(RETURN_TYPE == DJangoConnection.STRING)
                return this.readInputStream(inputStream);
              else
                return inputStream;
          }
        } catch(ConnectionNotFoundException ex) {
            ex.printStackTrace();
        } finally {
            if(httpConnection != null) httpConnection.close();
        }
        return "Error: " + RETURN_TYPE;
    }

    private void postEncodedData(HttpConnection httpConnection, String encodedData) throws IOException {
        // application/octet-stream, raw binary data
        // application/x-www-form-urlencoded, name-value pairs
        String agent = "Codeinn v1.0";
        String type = "application/x-www-form-urlencoded";
        httpConnection.setRequestMethod(HttpConnection.POST);
        httpConnection.setRequestProperty( "User-Agent", agent );
        httpConnection.setRequestProperty( "Content-Type", type );
		httpConnection.setRequestProperty( "Content-Length", ""+encodedData.length() );
        OutputStream outputStream = httpConnection.openOutputStream();
        try {
            outputStream.write( encodedData.getBytes() );
        } catch(IOException ex) {
            ex.printStackTrace();
        } finally {
            if(outputStream != null) outputStream.close();
        }
    }

    private String readInputStream(InputStream inputStream) throws IOException {
        StringBuffer stringBuffer = new StringBuffer();
        try {
            int character = 0;
            while((character = inputStream.read()) != -1) {
                stringBuffer.append((char)character);
            }
        } catch(IOException ex) {
            ex.printStackTrace();
        } finally {
            if(inputStream != null) inputStream.close();
        }
        return stringBuffer.toString();
    }

    private String encode(String[] keys, String[] values) {
        //"user="+user+"&password="+password
        String encodedData = "";
        for(int i=0; i<keys.length; i++) {
            encodedData += keys[i] + "=" + values[i] + "&";
        }
        // Remove the last ampersand
        encodedData = encodedData.substring(0, encodedData.length()-1);
        System.out.println("    encoded data: "+encodedData);
        return encodedData;
    }
}